/**
 * 
 */
package com.sqltojson.resource;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import com.google.common.collect.Maps;
import com.sqltojson.core.Resultat;
import com.sqltojson.dao.ExecuteQueryDao;
import com.sqltojson.dao.QueryDao;
import com.sqltojson.exception.QueryNotFoundException;
import com.sqltojson.exception.RequestServiceException;
import com.sqltojson.service.RequestService;
import com.sqltojson.service.RequestServiceImpl;
import com.sqltojson.util.Util;

/**
 * Execute la requete.
 */
public class RequestImpl implements Request {

	/** */
	private final RequestService requestService;

	/**
	 * @throws RequestServiceException echec lors de l'instantiation des objets
	 * 
	 */
	public RequestImpl() throws RequestServiceException {
		DataSource dataSource;
		try {
			final InitialContext ctx = new InitialContext();
			dataSource = (DataSource) ctx.lookup(Util.PROP.getProperty(Util.DB_JNDI_NAME));
		} catch (final NamingException e) {
			throw new RequestServiceException("Erreur lors de la recuperation de la datasource", e);
		}
		
		final RequestServiceImpl requestServiceImpl = new RequestServiceImpl();
		final ExecuteQueryDao executeQueryDao = new ExecuteQueryDao();
		executeQueryDao.setDataSource(dataSource);
		
		requestServiceImpl.setExecuteQueryDao(executeQueryDao);
		final QueryDao queryDao = new QueryDao();
		requestServiceImpl.setQueryDao(queryDao);
		this.requestService = requestServiceImpl;
	}

	public Resultat query(final String nameQuery, final UriInfo ui)
			throws WebApplicationException {
		final Map<String, String> transform = transform(ui.getQueryParameters());
		try {
			return requestService.query(nameQuery, transform);
		} catch (final QueryNotFoundException e) {
			throw new WebApplicationException(e, Response
					.status(Response.Status.NOT_FOUND)
					.entity(e.getMessage()).build());
		} catch (final RequestServiceException e) {
			throw new WebApplicationException(e, Response
					.status(Response.Status.INTERNAL_SERVER_ERROR)
					.entity(e.getMessage()).build());
		}
	}

	/**
	 * @param pathParameters
	 * @return
	 */
	private Map<String, String> transform(
			final MultivaluedMap<String, String> pathParameters) {
		final Map<String, String> maps = Maps.newHashMap();
		for (final Entry<String, List<String>> entry : pathParameters.entrySet()) {
			final Iterator<String> value = entry.getValue().iterator();
			if (value.hasNext()) {
				maps.put(entry.getKey(), value.next());
			}
			if (value.hasNext()) {
				throw new WebApplicationException(Response
						.status(Response.Status.BAD_REQUEST)
						.entity("Les listes ne sont pas gerees").build());
			}

		}
		return maps;
	}
}
